iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 17
2
自我挑戰組

JavaScript 試煉之旅系列 第 17

JavaScript 嚴格模式(Strict mode)

  • 分享至 

  • xImage
  •  

簡單介紹

嚴格模式(strict mode) 在ES5被引進,提供開發者能夠在語法更為嚴謹、受限的模式下進行開發,彌補了 JavaScript 的一些重要缺陷。

也提供了更強大的檢查與更高的安全性。

怎麼使用嚴格模式(strict mode)

當設定 'use strict' 或者 "use strict",就代表後續的程式碼處於嚴格模式下,但依據設定的位置不同,則嚴格模式的有效範圍也不同:

  1. 在全域設定的話,代表全部的程式碼都會處於嚴格模式(strict mode);
  2. 在函式中設定,則嚴格模式(strict mode)的有效範圍則侷限在該函式底下的所有程式碼。

來看看測試例子:

"use strict"

a = 3 ;
function test(){
  b = 5;
}
test();

Day17-1

"use strict"

function test(){
  b = 5;
}
test();

Day17-2

從上面兩個結果可以得到,在全域設定嚴格模式(strict mode),則所有的程式碼都會在嚴格模式的有效範圍內。

接下再來看看另外一個例子:把 'use strict' 寫在函式內

a = 3;

function test(){
"use strict"
  b = 5;
}
test();

Day17-3

從結果可以得知: 嚴格模式(strict mode)設定在函式內時,則影響的範圍就只有函式內而已,而全域變數 a因為不在嚴格模式(strict mode)的有效範圍內,所以會依照原本的方式,被隱性的宣告成全域變數(不會報錯)。

細談嚴格模式(strict mode)

再來要來提提在於嚴格模式(strict mode)下,是什麼做了調整,調整了什麼

  1. 嚴格模式(strict mode)中,不允許使用 with 述句
'use strict'

var a, x, y;
var r = 10;

with (Math) {
  a = PI * r * r;
  x = r * cos(PI);
  y = r * sin(PI / 2);
}

Day17-4

with() 述句會增加程式碼閱讀的困難度,以及變數的查詢,所以在嚴格模式(strict mode)被撇除。

  1. 嚴格模式(strict mode)中,所有變數都必須被宣告,否則會報錯(ReferenceError)。 但在非嚴格模式則視為隱性的宣告全域變數。
a = 3;

function test(){
"use strict"
  b = 5;
}
test();

Day17-3

如同前面所提,所有的變數都必須被宣告才可以。

  1. 嚴格模式(strict mode)中,不是當作方法的函式:
    • this 值為 undefined
    • 若是使用 call(),apply(),bind()等方法指定this那麼 this 的值就依照其語法設定而決定。
    • 但若是使用 call(),apply(),bind()等方法指定this,但參數為nullundefined,則 thisnullundefined。不會像非嚴格模式下會自動轉成全域物件。

在非嚴格模式下, this 會指向全域物件,所以可以取得全域變數 age 的值。

var age = 22;

function getAge(){
  console.log(this);
  console.log(this.age);
}
getAge();

Day17-5

透過如 call() 設定 this 的值,當值為 null 時,則指向全域物件,所以可以獲得和前一個一樣的結果

var age = 22;

function getAge(){
  console.log(this);
  console.log(this.age);
}
getAge.call(null);

但在嚴格模式下, this 會是 undefined ,所以想取得全域變數 age 的值就會報錯。

'use strict'

var age = 22;

function getAge(){
  console.log(this);
  console.log(this.age);
}
getAge();

Day17-6

如果透過 call() 設定 this 的值,當值為 nullthis 值就為 null ,不會指向全域物件。

'use strict'

var age = 22;

function getAge(){
  console.log(this);
}
getAge.call(null);

Day17-7

  1. 嚴格模式(strict mode)中,對於不可寫入(nonwritable)的物件或不可擴充(nonextensible)的物件嘗試建立新特性會報錯。 但在非嚴格模式下雖然會失敗,但不會有錯誤訊息。
var obj = {};
Object.defineProperty(obj,"age",{
  value: 22,
  writable: false,
  configurable: false
})

obj.age = 25;
console.log(obj);

Day17-8

但在嚴格模式下,就會提供相關的錯誤訊息了。

'use strict'
var obj = {};
Object.defineProperty(obj,"age",{
  value: 22,
  writable: false,
  configurable: false
})

obj.age = 25;
console.log(obj);
  • 物件為唯讀(read only)時,提供相關的錯誤訊息。

Day17-9

  • 物件為非擴充性,提供相關的錯誤訊息。
'use strict'
var obj = {};
Object.defineProperty(obj,"age",{
  value: 22,
  writable: false,
  configurable: false
})

Object.seal(obj);
obj.name = "Bill";
console.log(obj);

Day17-10

  1. 嚴格模式(strict mode)中,eval() 不能宣告變數或者定義函式。 但在非嚴格模式下可以。

在非嚴格模式下,在 eval() 中宣告變數是被允許的。

eval('var age = 22');
console.log(age);

Day17-11

但在嚴格模式,直接在 eval() 中宣告變數則會報錯。

'use strict'
eval('var age = 22');
console.log(age);

Day17-12

  1. 嚴格模式(strict mode)中的 arguments 物件:
    • 是唯讀的
    • 對於arguments.calleearguments.caller 存取會報錯
'use strict'
function test(a,b){
  console.log(arguments);
  console.log(arguments.callee);
}
test(1,2);

Day17-13

  1. 在ES6之前 ,嚴格模式(strict mode)中對於物件特性重複宣告會報錯,但非嚴格模式中不會發生錯誤。 但ES6之後並不會有任何錯誤訊息提示

MDN: strict mode

Day17-14

  1. 嚴格模式(strict mode)中, delete 如果不是用於刪除物件特性,就會報錯。 但在非嚴格模式下則是不會有錯誤訊息,但會回傳 false

非嚴格模式下,使用 delete 用於刪除非物件的特性,只會回傳false

var age = 22;
delete age;

Day17-15

但嚴格模式下就會報錯。

'use strict'
var age = 22;
delete age;

Day17-16

  1. 嚴格模式(strict mode)中, 函式的參數若是重複命名會報錯。 但在非嚴格模式下則不會。

非嚴格模式下,下列的程式碼並不會報錯。

function test(a,a){
  console.log(a);
}
test(1,2);

但嚴格模式下,參數重複命名就會提示相關錯誤訊息。

'use strict'
function test(a,a){
  console.log(a);
}
test(1,2);

Day17-17

關於嚴格模式的介紹就到這裡囉!

明天見~


上一篇
JavaScript class 類別
下一篇
JavaScript ES6 解構賦值
系列文
JavaScript 試煉之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言